//! @Author: DengLibin
//! @Date: Create in 2023-11-06 17:25:05
//! @Description: hello world

use std::collections::HashMap;

use axum::{
    body::Body, extract::Multipart,

     extract::Query, http::Request, response::Html, Form, Json,
};



use log::{ info, warn};


use serde::{Deserialize, Serialize};
use serde_json::{json, Value};

use crate::global::{GlobalResult, Resdata, self, check_result};

#[derive(Debug, Serialize, Deserialize)]
pub struct User {
    pub id: u64,
    pub name: String,
}

/// @Author: DengLibin
/// @Date: Create in 2023-11-06 17:26:27
/// @Description: hello world
pub async fn hello_world() -> Html<&'static str> {
    info!("get hello world");
    Html("<h1>Hello, World!</h1>")
}

/// @Author: DengLibin
/// @Date: Create in 2023-11-06 18:08:10
/// @Description: json
pub async fn json() -> Json<Value> {
    Json(json!(User {
        id: 234_u64,
        name: "张三".into()
    }))
}

/// @Author: DengLibin
/// @Date: Create in 2023-11-07 16:13:31
/// @Description: 获取查询参数
pub async fn query(Query(params): Query<HashMap<String, String>>) -> Json<Value> {
    for ele in params.iter() {
        println!("{}-{}", ele.0, ele.1);
    }
    Json(json!(params))
}
/// @Author: DengLibin
/// @Date: Create in 2023-11-07 16:30:24
/// @Description: 获取请求体
pub async fn string_body(body: String) -> Json<Value> {
    Json(json!(body))
}

/// @Author: DengLibin
/// @Date: Create in 2023-11-07 16:30:40
/// @Description:
pub async fn request(request: Request<Body>) -> Json<Value> {
    let r = request.uri();
    Json(json!(r.path()))
}

/// @Author: DengLibin
/// @Date: Create in 2023-11-07 16:35:27
/// @Description: 接收json
pub async fn json_obj(Json(user): Json<User>) -> Json<User> {
    Json(user)
}

/// @Author: DengLibin
/// @Date: Create in 2023-11-07 16:35:27
/// @Description: 接收json
pub async fn json_arr(Json(users): Json<Vec<User>>) -> Json<Vec<User>> {
    Json(users)
}

/// @Author: DengLibin
/// @Date: Create in 2023-11-07 16:35:27
/// @Description: 接收 form
pub async fn form_obj(Form(user): Form<User>) -> Json<User> {
    Json(user)
}

/// @Author: DengLibin
/// @Date: Create in 2024-06-28 15:23:33
/// @Description: 
pub async fn test_log()->Html<&'static str>{
    info!(target: "info_logger", "this is info log");
    warn!(target: "warn_logger", "this is warn log");
    log::error!(target: "error_logger", "this is error log");

    Html("<h1>Ok Log</h1>")
}


/// @Author: DengLibin
/// @Date: Create in 2023-11-07 18:50:04
/// @Description: 上传文件 上传大文件耗内存(可以使用分块上传，然后再合并)
pub async fn upload(multipart: Multipart) -> Json<Resdata<()>> {
    let r: GlobalResult<()> = save_file(multipart).await;

    Json(Resdata::ok_result(r))
}
async fn  save_file(mut multipart: Multipart) ->GlobalResult<()>{
    loop {
        let r = multipart.next_field().await;
        let  o = global::check_result(r)?;
                if let Some(field) = o {
                    let x = field.file_name();
                    if let Some(n) = x {
                        let filename = n.to_string();
                        // println!("文件名:{}", filename);
                        let br = field.bytes().await;
                        
                        let bytes = global::check_result(br)?;
                        
                        let x = tokio::fs::write(format!("upload/{}", filename), &bytes).await;
                        check_result(x)?;
                    }
                }else {
                    break;
                }
    }
    Ok(())

}
